package com.bwie.es.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bwie.common.domain.Shop;
import com.bwie.common.domain.request.ShopRequest;
import com.bwie.common.result.PageResult;
import com.bwie.common.result.Result;
import com.bwie.common.utils.StringUtils;
import com.bwie.es.feign.GoodsFeign;
import com.bwie.es.service.EsService;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class EsServiceimpl implements EsService {
    private final static String INDEX_NAME = "shop";

    @Autowired
    private RestHighLevelClient client;

    @Override
    public void esAdd(List<Shop> data) {
        BulkRequest bulkRequest = new BulkRequest(INDEX_NAME);

        try {
            data.forEach(item->{
                bulkRequest.add(new IndexRequest()
                        .id(String.valueOf(item.getId()))
                        .source(JSON.toJSONString(item), XContentType.JSON));
            });
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Result<PageResult<Shop>> EsList(ShopRequest shopRequest) {
        ArrayList<Shop> shops = new ArrayList<>();
        long total=0;
        try {
            SearchRequest searchRequest = new SearchRequest("shop");

            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

            //模糊查询
            if(!StringUtils.isEmpty(shopRequest.getName())){
                boolQueryBuilder.must(QueryBuilders.matchQuery("name",shopRequest.getName()));
            }
            searchSourceBuilder.query(boolQueryBuilder);

            //分页
            searchSourceBuilder.from((shopRequest.getPageNum()-1)*shopRequest.getPageSize());
            searchSourceBuilder.size(shopRequest.getPageSize());
            searchRequest.source(searchSourceBuilder);

            //高亮
            searchSourceBuilder.highlighter(new HighlightBuilder().field("name").preTags("<span style=\"color: red\">").postTags("</span>"));

            SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = search.getHits();
            total=hits.getTotalHits().value;
            for (SearchHit hit : hits.getHits()) {
                String sourceAsString = hit.getSourceAsString();

                Shop shop = JSONObject.parseObject(sourceAsString, Shop.class);

                Map<String, HighlightField> highlightFields = hit.getHighlightFields();

                HighlightField name = highlightFields.get("name");

                if(name!=null){
                    StringBuilder stringBuilder = new StringBuilder();

                    for (Text fragment : name.getFragments()) {
                        stringBuilder.append(fragment);
                    }

                    shop.setId(Integer.valueOf(hit.getId()));
                    shop.setName(stringBuilder.toString());
                }

                shops.add(shop);
            }


        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return PageResult.toResult(total,shops);
    }
}
